﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using A2DFramework.HttpLoadBalancer.HttpProtocal;
using A2DFramework.HttpLoadBalancer.Utility;

namespace A2DFramework.HttpLoadBalancer.Parsers.ConcreteParsers
{
    public static class Helper
    {
        public static HttpProtocalVersions ParseHttpVersion(string versionCode)
        {
            HttpProtocalVersions version = HttpProtocalVersions.Unknow;
            if (versionCode.Equals("HTTP/1.0", StringComparison.OrdinalIgnoreCase))
                version = HttpProtocalVersions.HTTP10;
            else if (versionCode.Equals("HTTP/1.1", StringComparison.OrdinalIgnoreCase))
                version = HttpProtocalVersions.HTTP11;
            return version;
        }
        public static string ConvertHttpVersion(HttpProtocalVersions version)
        {
            string httpVersion = "HTTP/1.1";
            if (version == HttpProtocalVersions.HTTP10)
                httpVersion = "HTTP/1.0";
            else if (version == HttpProtocalVersions.HTTP11)
                httpVersion = "HTTP/1.1";
            return httpVersion;
        }

        public static HttpRequestActions ParseHttpAction(string actionCode)
        {
            HttpRequestActions action = HttpRequestActions.Unknow;
            if (actionCode.Equals("CONNECT", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.CONNECT;
            else if (actionCode.Equals("DELETE", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.DELETE;
            else if (actionCode.Equals("GET", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.GET;
            else if (actionCode.Equals("HEAD", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.HEAD;
            else if (actionCode.Equals("OPTIONS", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.OPTIONS;
            else if (actionCode.Equals("POST", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.POST;
            else if (actionCode.Equals("PUT", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.PUT;
            else if (actionCode.Equals("TRACE", StringComparison.OrdinalIgnoreCase))
                action = HttpRequestActions.TRACE;
            return action;
        }
        public static string ConvertHttpAction(HttpRequestActions action)
        {
            return action.ToString();
        }

        public static string[] ParseHeaderBody(string rawHttpText)
        {
            int splitIndex = -1;

            splitIndex = rawHttpText.IndexOf(string.Format("{0}{0}", Consts.CRLF));

            if (splitIndex == -1)
                throw new Exception("无效报文，无法定位Http头与Body");

            string headerString = rawHttpText.Substring(0, splitIndex);
            string bodyString = rawHttpText.Substring(splitIndex + Consts.CRLF.Length);

            int first_crlf_Index=headerString.IndexOf(Consts.CRLF);
            string requestLineString = headerString.Substring(0, first_crlf_Index);
            headerString = headerString.Substring(first_crlf_Index + Consts.CRLF.Length);

            return new string[] { requestLineString, headerString, bodyString };
        }

        public static HttpHeadersCollection ParseHeaders(string headerString)
        {
            List<HttpProtocal.HttpHeaderEntity> headers = new List<HttpHeaderEntity>();

            string[] headerRows = headerString.Split(Consts.CRLF.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
            foreach (var row in headerRows)
            {
                HttpHeaderEntity header = Parsers.HttpHeaderParser.Parse(row);
                headers.Add(header);
            }

            HttpHeadersCollection collection = new HttpHeadersCollection();
            collection.AddRange(headers);
            return collection;
        }

        internal static RequestLine ParseRequestLine(string requestLineString)
        {
            return Parsers.RequestLineParser.Parse(requestLineString);
        }

        internal static ResponseStatusLine ParseResponseLine(string responseLineString)
        {
            return Parsers.ResponseHeaderParser.Parse(responseLineString);
        }

        public static string ConvertHttpHeaders(HttpHeadersCollection headers)
        {
            string strHeaders = string.Empty;
            string headerFormat = "{0}: {1}{2}";

            foreach (var header in headers)
            {
                string tmpHeader = string.Format(headerFormat, header.Key, header.Value, Consts.CRLF);
                strHeaders += tmpHeader;
            }

            return strHeaders;
        }

        public static byte[] GetHttpBodyBytes(byte[] firstData, byte[] deepData)
        {
            Console.WriteLine("begin");
            List<byte> allData = new List<byte>();
            allData.AddRange(firstData);
            if (deepData!=null)
                allData.AddRange(deepData);


            List<byte> crlf = new List<byte>();
            crlf.Add((byte)'\r');
            crlf.Add((byte)'\n');
            crlf.Add((byte)'\r');
            crlf.Add((byte)'\n');

            int crlfSplitIndex = -1;
            for (int i = 0; i < allData.Count - 4; i++)
            {
                if (allData[i].Equals(crlf[0])
                    && allData[i + 1].Equals(crlf[1])
                    && allData[i + 2].Equals(crlf[2])
                    && allData[i + 3].Equals(crlf[3])
                    )
                {
                    crlfSplitIndex = i;
                    break;
                }
            }

            byte[] bodyBytes = allData.Skip(crlfSplitIndex + 4).ToArray();
            Console.WriteLine("end");
            return bodyBytes;
        }
    }
}
